package com.zhuhjay.common.utils;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.zhuhjay.common.exception.CustomException;

import java.io.UnsupportedEncodingException;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * @author ZhuHJay
 * @date 2022/3/21 19:26
 */
public class JwtUtils {

    /** 私钥 **/
    private static final String SECRET = "secret-lock-zhuhjay";
    /** token过期时间(单位s)  **/
    private static final int EXPIRATION_TIME = 2 * 60 * 60;
    /** jwt的头部map **/
    private static final Map<String, Object> HEADERS_MAP = new HashMap<>();

    static {
        HEADERS_MAP.put("alg", "HS256");
        HEADERS_MAP.put("typ", "JWT");
    }

    /**
     * 生成Token
     * @param username 负载数据
     * @return token串
     */
    public static String generateToken(String username) {
        // 过期时间，两个小时时间
        Calendar nowTime = Calendar.getInstance();
        nowTime.add(Calendar.SECOND, EXPIRATION_TIME);
        Date expiration = nowTime.getTime();
        try {
            return JWT.create()
                    .withHeader(HEADERS_MAP)
                    // 设置负载数据
                    .withClaim("username", username)
                    // 设置过期的日期
                    .withExpiresAt(expiration)
                    // 签发时间
                    .withIssuedAt(new Date())
                    // 加密
                    .sign(Algorithm.HMAC256(SECRET));
        } catch (UnsupportedEncodingException e) {
            throw new CustomException("token生成错误");
        }
    }

    /**
     * 验证Token是否过期并解密
     * @param token token串
     * @return 返回解密数据
     * @throws Exception token失效 || 不是token
     */
    public static String verifyToken(String token) throws Exception {
        JWTVerifier verifier = JWT.require(Algorithm.HMAC256(SECRET)).build();
        DecodedJWT jwt;
        try {
            //核实token
            jwt = verifier.verify(token);
        } catch (Exception e) {
            throw new CustomException("Token失效");
        }
        return jwt.getClaims().get("username").asString();
    }
}
